package com.scpii.api.service.user.impl;

import java.text.MessageFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import com.scpii.api.common.Constants;
import com.scpii.api.common.base.ResponseThreadlocal;
import com.scpii.api.common.exception.DotNotAllowRegisterException;
import com.scpii.api.common.exception.InvalidRequestException;
import com.scpii.api.common.exception.InvalidValidCodeException;
import com.scpii.api.domain.auth.UserConfigs;
import com.scpii.api.domain.auth.UsersInfoDetails;
import com.scpii.api.domain.common.Field;
import com.scpii.api.domain.common.FieldValues;
import com.scpii.api.domain.ec.Address;
import com.scpii.api.domain.user.Users;
import com.scpii.api.persistence.auth.UserConfigsMapper;
import com.scpii.api.persistence.common.FieldMapper;
import com.scpii.api.persistence.common.FieldValuesMapper;
import com.scpii.api.persistence.ec.AddressMapper;
import com.scpii.api.persistence.user.UsersMapper;
import com.scpii.api.service.app.AppConfigsService;
import com.scpii.api.service.user.UsersService;
import com.scpii.api.util.CommonUtil;
import com.scpii.api.util.PrincipalUtil;
import com.scpii.api.util.RegisterVerifyUtil;
import com.scpii.api.util.SmsUtil;

@Service
public class UsersServiceImpl implements UsersService {

	@Resource
	private UsersMapper usersMapper;

	@Resource
	private FieldValuesMapper fieldValuesMapper;

	@Resource
	private FieldMapper fieldMapper;

	@Resource
	private UserConfigsMapper userConfigsMapper;

	@Resource
	private AddressMapper addressMapper;

	@Resource
	private AppConfigsService appConfigsService;

	@Override
	public void insertUsersValidCode(String phone) {
		Users record = new Users();
		record.setUserName(phone);
		record.setAppId(PrincipalUtil.getPrincipal().getAppId());
		record.setProvider(Constants.ALL_USER_PROVIDERS.get("PHONE"));
		Users persistUsers = usersMapper.selectBySelective(record);
		if (persistUsers != null) {
			String validCode = CommonUtil.getRandomNumberString(4);
			persistUsers.setValidCode(validCode);
			persistUsers.setUpdateDt(new Date());
			persistUsers.setLastActivityDt(new Date());
			usersMapper.updateByPrimaryKeySelective(persistUsers);
			SmsUtil.sendSms(new String[] { phone }, MessageFormat.format(
					Constants.SMS_SEND_TEMPLATE, validCode));
		} else {
			Map<String, String> allow = appConfigsService.selectByKeys(
					PrincipalUtil.getPrincipal().getAppId(), new String[] {
							Constants.REGISTER_ALLOW_KEY,
							Constants.REGISTER_ALLOW_AREA });
			if (!RegisterVerifyUtil.verifyPhone(phone, allow == null ? null
					: allow)) {
				ResponseThreadlocal.getResponse().setTips("系统不允许注册或用户不存在");
				throw new DotNotAllowRegisterException();
			}
			String validCode = CommonUtil.getRandomNumberString(4);
			Users users = new Users();
			users.setUserAilas(phone);
			users.setUserName(phone);
			users.setValidCode(validCode);
			users.setPassword(DigestUtils.md5Hex(validCode));
			users.setCreateDt(new Date());
			users.setUserType(Constants.USERS_TYPES.get("NOT_VERIF"));
			users.setPasswordFormat(Constants.USER_PASSWORD_FORMAT);
			users.setAppId(PrincipalUtil.getPrincipal().getAppId());
			users.setAuthorities(StringUtils.join(Constants.ROLES_ARRAY, ","));
			users.setProvider(Constants.ALL_USER_PROVIDERS.get("PHONE"));
			users.setPhoneNumber(phone);
			users.setLastActivityDt(new Date());
			usersMapper.insertSelective(users);

			UserConfigs userConfigs = new UserConfigs();
			userConfigs.setUserId(users.getId());
			userConfigsMapper.insertSelective(userConfigs);

			SmsUtil.sendSms(new String[] { phone }, MessageFormat.format(
					Constants.SMS_SEND_TEMPLATE, validCode));

		}
	}

	@Override
	public Users updatePasswordByValidCodeAndUserName(String validCode,
			String userName, String password) {
		Users record = new Users();
		record.setValidCode(validCode);
		record.setUserName(userName);
		record.setAppId(PrincipalUtil.getPrincipal().getAppId());
		Users peristUser = usersMapper.selectBySelective(record);
		if (peristUser == null) {
			throw new InvalidValidCodeException("coult't find validcode "
					+ validCode + " by user " + userName);
		}
		peristUser.setPassword(DigestUtils.md5Hex(password));
		peristUser.setValidCode(CommonUtil.getRandomString(8));
		usersMapper.updateByPrimaryKeySelective(peristUser);
		return peristUser;
	}

	@Override
	public Users updateUsers(String userAliasName, String userAvatar,
			List<FieldValues> fieldValues) {
		UsersInfoDetails usersInfoDetails = PrincipalUtil.getPrincipal();
		if (usersInfoDetails == null) {
			throw new UsernameNotFoundException(
					"could't not find auth in this securityContext");
		}
		Users persistUsers = usersMapper.selectByPrimaryKey(usersInfoDetails
				.getId());
		if (persistUsers == null) {
			return null;
		}
		persistUsers.setUserAilas(userAliasName);
		persistUsers.setAvatar(userAvatar);
		if (persistUsers.getUserType().equals(
				Constants.USERS_TYPES.get("NOT_VERIF"))) {
			persistUsers.setUserType(Constants.USERS_TYPES.get("NORMAL"));
			persistUsers.setLastActivityDt(new Date());
			persistUsers.setLastLoginDt(new Date());
		}
		usersMapper.updateByPrimaryKeySelective(persistUsers);
		if (fieldValues == null) {
			return persistUsers;
		}
		Set<Long> ids = new HashSet<Long>();
		for (FieldValues fieldValue : fieldValues) {
			if (fieldValue != null) {
				ids.add(fieldValue.getFieldId());
			}
		}
		if (ids.size() != 0) {
			fieldValuesMapper.deleteByIds(ids, usersInfoDetails.getId());
		}
		for (FieldValues param : fieldValues) {
			if (param.getFieldId() == null) {
				throw new InvalidRequestException(
						"param fieldid could't be null");
			}
			if (param.getValueStr() == null) {
				throw new InvalidRequestException(
						"param valuestr could't be null");
			}
			if (StringUtils.isBlank(param.getValueStr())) {
				continue;
			}
			Field field = fieldMapper.selectByPrimaryKey(param.getFieldId());
			if (field != null
					&& Field.FIELD_USER_KEY.get(field.getName()) != null) {
				usersMapper.updateValueByColumnName(PrincipalUtil
						.getPrincipal().getId(), Field.FIELD_USER_KEY.get(field
						.getName()), param.getValueStr());
			}
			if (field != null && field.getName().equals("地址")) {
				Address persistAddress = addressMapper
						.selectByPrimaryKey(persistUsers.getAddressId());
				if (persistAddress == null) {
					Address addressRecord = new Address();
					addressRecord.setAddressLine(param.getValueStr());
					addressRecord.setTargetId(persistUsers.getId());
					addressRecord.setCreateBy(persistUsers.getId());
					addressRecord.setCreateDt(new Date());
					addressMapper.insertSelective(addressRecord);
					persistUsers.setAddressId(addressRecord.getAddressId());
					usersMapper.updateByPrimaryKeySelective(persistUsers);
				} else {
					persistAddress.setAddressLine(param.getValueStr());
					persistAddress.setTargetId(persistUsers.getId());
					persistAddress.setUpdateBy(persistUsers.getId());
					persistAddress.setUpdateDt(new Date());
					addressMapper.updateByPrimaryKeySelective(persistAddress);
				}
			}
			if (field != null && field.getName().equals("昵称")) {
				param.setValueStr(userAliasName != null ? userAliasName : param
						.getValueStr());
			}
			param.setAppId(usersInfoDetails.getAppId());
			param.setTargetId(usersInfoDetails.getId());
			param.setCreateDt(new Date());
			param.setCreateBy(usersInfoDetails.getId());
			fieldValuesMapper.insertSelective(param);
		}
		return persistUsers;
	}

	@Override
	public Users selectByPrimaryKey(Long id) {
		return usersMapper.selectByPrimaryKey(id);
	}

	@Override
	public void updateRankPointById(Long id, Integer addPoints) {
		usersMapper.updateRankPointById(id, addPoints);
	}

}
